#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <unistd.h>
#include <string.h>
// 万能指针 void
typedef struct
{
    // 成员变量。
    unsigned id;   // unsigned 就是 unsigned int
    char name[20]; // 用字符数组来保存名字。
} studentInfStc;

typedef struct
{
    int cmdid;
    void *cmddata;
} myCmdStc;

typedef enum
{
    myCmd_Char = 0,
    myCmd_Int,
    myCmd_Float,
    myCmd_Student,
} myCmdEnum;

void docommand(myCmdStc *mycmd)
{
    if(!(mycmd && mycmd->cmddata))
    {
        perror("do command ptr error\n");
        return;
    }
    switch (mycmd->cmdid)
    {
    case myCmd_Char:
    {
        char *tmpptr = mycmd->cmddata;
        printf("char data=%d\n", tmpptr[0]);
        break;
    }
    case myCmd_Int:
    {
        int *tmpptr = mycmd->cmddata;
        printf("int data=%d\n", tmpptr[0]);
        break;
    }
    case myCmd_Float:
    {
        float *tmpptr = mycmd->cmddata;
        printf("float data=%f\n", tmpptr[0]);
        break;
    }
    case myCmd_Student:
    {
        studentInfStc *tmpptr = mycmd->cmddata;
        printf("studentInfStc data=%d\n", tmpptr->id);
        break;
    }
    default:
    {
        printf("unkown cmdid: %d\n", mycmd->cmdid);
        break;
    }
    }
}

int main(int argc, char **argv)
{
    studentInfStc tmpstudt = {1, "hc"};
    void *tmpvoid = &tmpstudt;// 万能指针直接赋值就可以。
    printf("void ptr=%p, void + 1 ptr=%p\n", tmpvoid, tmpvoid + 1);
    {
        char *tmpptr = tmpvoid;
        printf("char ptr[0]=%d\n", tmpptr[0]);
    }
    {
        studentInfStc *tmpptr = tmpvoid;// 直接转为其他类型。
        printf("student ptr.id=%d\n", tmpptr->id);
    }

    // function
    {
        myCmdStc tmpcmd;
        {
            char tmpval = 12;
            tmpcmd.cmdid = myCmd_Char;
            tmpcmd.cmddata = &tmpval;
            docommand(&tmpcmd);
        }
        {
            int tmpval[1] = {22};
            tmpcmd.cmdid = myCmd_Int;
            tmpcmd.cmddata = &tmpval;// 效果一样
            // tmpcmd.cmddata = tmpval;
            docommand(&tmpcmd);
        }
        {
            float *tmpval = (float *)malloc(sizeof(float));
            tmpval[0] = 33.3f;
            tmpcmd.cmdid = myCmd_Float;
            // tmpcmd.cmddata = &tmpval;// 效果不一样, 会导致崩溃！
            tmpcmd.cmddata = tmpval;
            docommand(&tmpcmd);
            free(tmpcmd.cmddata);// 记得释放。经常忘记。
        }
        {
            tmpstudt.id = 44;
            tmpcmd.cmdid = myCmd_Student;
            tmpcmd.cmddata = &tmpstudt;
            docommand(&tmpcmd);
        }
    }
    return 1;
}
